package com.zx.util;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Project: dataShare
 * @Title: SimpleThreadPool
 * @Description: 简单线程池, 最小3个, 最大15个
 * @author: zhangx
 * @date: 2017年9月27日 上午10:28:28
 * @company: webyun
 * @Copyright: Copyright (c) 2017
 * @version v1.0
 */
public abstract class  SimpleThreadPool {
	/** 最小活跃线程数*/
	private static final int MIN_POOL_SIZE = 5;
	
	/** 最大线程数*/
	private static final int MAX_POOL_SIZE = 15;
	
	/** 线程存活时间，单位秒*/
	private static final long KEEP_ALIVE_TIME = 15L;
	
	/** 有界队列，容量是5个 */
	private static final BlockingQueue<Runnable> BLOCKING_QUEUE = new ArrayBlockingQueue<>(5);
	
	/** 线程池 */
	private static ThreadPoolExecutor POOL;
	
	static {
		/**
		 * 线程池初始化方法
		 * corePoolSize 核心线程池大小----10
		 * maximumPoolSize 最大线程池大小----30
		 * keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间----30+单位TimeUnit
		 * TimeUnit keepAliveTime时间单位----TimeUnit.MINUTES
		 * workQueue 阻塞队列----new ArrayBlockingQueue<Runnable>(10)====10容量的阻塞队列
		 * threadFactory 新建线程工厂----new CustomThreadFactory()====定制的线程工厂
		 * rejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,
		 * 							即当提交第41个任务时(前面线程都没有执行完,此测试方法中用sleep(100)),
		 * 						          任务会交给RejectedExecutionHandler来处理
		 */
		POOL = new ThreadPoolExecutor(MIN_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME,
				TimeUnit.SECONDS, BLOCKING_QUEUE, new CustomThreadFactory(), new CustomRejectedExecutionHandler());
	}
	
	/**
	 * @Title: 提交并执行线程
	 * @param task
	 * @author: zhangx
	 * @date: 2017年9月30日 下午3:22:32
	 * @version v1.0
	 */
	public static void submit(Thread task){
		POOL.execute(task);
	}
	
	/**
	 * @Title: 样例
	 * @param args
	 * @author: zhangx
	 * @date: 2017年9月27日 上午10:34:48
	 * @version v1.0
	 */
	public static void main(String[] args) {
		//创建一个线程
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>");
					System.out.println(Thread.currentThread().getName());
					Thread.sleep(5000);
					System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		for (int i = 0; i < 10; i++) {
			//向线程池中提交两个线程去执行。
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
			SimpleThreadPool.submit(t1);
		}
		//关闭线程池
		POOL.shutdown();
	}
	
	private static class CustomThreadFactory implements ThreadFactory {

		private AtomicInteger count = new AtomicInteger(0);
		
		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r);
			String threadName = SimpleThreadPool.class.getSimpleName() + count.addAndGet(1);
			System.out.println(threadName);
			t.setName(threadName);
			return t;
		}
	}
	
	
	private static class CustomRejectedExecutionHandler implements RejectedExecutionHandler {

		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			// 记录异常
			// 报警处理等
			System.out.println("error.............");
		}
	}
	
}
